﻿/**
 * jQuery twiDataTable plugin
 * @author: feitianxinhong  http://xuzhihong1987.blog.163.com/
 * @version 1.0.0
 * @create date:2014-10-17
 * @copyright (c) 2014 feitianxinhong/tyingsoft/twilight  http://www.tyingsoft.com
 * @example Visit 
 * @Require: bootstrap-3.2.0样式 和 twibootstrap-1.0.0.css 样式
 *
 * ------------------------------------------------------------------
 * 编号    版本号     作者              修改日期        修改内容
 * ------------------------------------------------------------------
 *  1      1.0.0     feitianxinhong    2014-10-17     创建文件
 *  2      1.1.0     feitianxinhong    2014-10-24     增加了选择框来支持多选、增加了部分方法
 *
 * ------------------------------------------------------------------
 */
(function ($) {
    var global = this;
    if (typeof Twi === 'undefined') {
        global.Twi = {
            emptyFn: function () { }
        };
    }
    Twi.global = global;

    /**
     * config配置说明：
     *
     * columns:[{
     *    text:      '表头标题【必填】',
     *    fieldName: '对应字段【必填】',
     *    dataType:  '数据类型，不填为字符串',
     *    width:     '列宽，不填则为自动',
     *    renderer:  '显示格式转换函数'
     *  }],
     * width:        'grid宽度，数字',
     * renderTo:     '表格呈现的位置，默认为body，如果为id，则格式为：#id',
     * rownumberer:  '是否显示行号，默认显示，如果为false时，不显示，可配置宽度width,默认为20px',
     * striped:      '是否隔行变色，default：true' , 
     * multiSelect:  '是否支持多选，default：false'
     *
     * 事件配置说明： 
     *         1、事件名做为config配置时，需加前缀on，如事件rowclick，配置时为onrowclick
     *         2、事件名全部为小写 【Sench Extjs 事件特殊命名规则】
     * ----------------------------------------------------------------
     *
     * 属性说明:  
     * 
     *
     * 私有变量为下划线为前缀：
     *
     * _headHtml:  Table表头HTML
     * _data：     数组，本地的数据存储
     * _lastSelected:{           //最后选择的记录信息, undefine 为未选择
     *       rowIndex:'',        //行索引，start with 0
     *       rowData:{}          //行数据，object
     * }
     * _handlers
     * ----------------------------------------------------------------
     * 
     * 事件说明：
     * rowclick(args)
     *     参数说明： 
     *              1、tableSelf : Twi.DataTable对象
     *              2、rowData:    行数据对象
     *              3、rowIndex：  行索引
     */
    Twi.DataTable = function (config) {
        var me = this;
        /**
         *默认配置项 
         */
        me.defaults = {
            renderTo: 'body',
            rownumberer: {
                text:'',
                width: 20
            },
            columns: [],
            striped: true,
            multiSelect:false
        };
        /**
         * 事件
         */
        me._handlers = {};

        config = config || {};
        config = $.extend({}, me.defaults, config);

        //是否需要显示行号
        config.needRowNumber = true;
        if (typeof config.rownumberer == 'boolean') {
            if (!config.rownumberer) {
                config.needRowNumber = false;
            }
            else {
                config.rownumberer = me.defaults.rownumberer; 
            }
        }

        me.config = config;
        me.frameId = "TwiDtPanel" + Math.floor(10000 * Math.random());
        me.id = "TwiDataTable" + Math.floor(10000 * Math.random()); //随机ID         
        me.titleId = "TwiDtTitle" + Math.floor(10000 * Math.random());

        /**
         *生成标题HTML
         */
        function getTitleHtml() {
            var titleHtml = '';
            if (config.title) {
                titleHtml = '<div id="' + me.titleId + '" class="panel-heading">' + config.title + '</div>';               
            }
            return titleHtml;
        }

        /*主框体*/
        var mainFrameHtml = '';
        mainFrameHtml += '<div id="' + me.frameId + '" class="panel panel-default">';
        mainFrameHtml += getTitleHtml();
        //mainFrameHtml +='<div class="panel-body">';
        //mainFrameHtml +='</div>';
        mainFrameHtml +='</div>';
        $(config.renderTo).append(mainFrameHtml);
        //宽度设置
        if (typeof me.config.width == 'number') {
            $('#' + me.frameId).css('width', me.config.width);
        }


        /**
         * 生成表头HTML
         */
        function getTableHeadHtml() {
            var headHtml = "";
            headHtml += '<thead>';
            headHtml += '<tr>';

            //行号列
            if (config.needRowNumber) {
                headHtml += '<th style="text-align:center;width:' + config.rownumberer.width + 'px;">' + config.rownumberer.text + '</th>';
            }

            //数据列
            for (var i = 0; i < config.columns.length; i++) {
                var col = config.columns[i];
                if (typeof col.width == 'number') {
                    headHtml += '<th style="width:' + col.width + 'px;">' + col.text + '</th>';
                }
                else {
                    headHtml += '<th>' + col.text + '</th>';
                }
            }

            headHtml += '</tr>';
            headHtml += '</thead>';
            return headHtml;
        }
        this._headHtml = getTableHeadHtml();

        /*表格*/
        var html = '';
        html += '<table id=' + me.id + ' class="table table-hover table-bordered';
        if (typeof me.config.striped == 'boolean' && me.config.striped) {
            //隔行变色
            html += ' table-striped';
        }
        html += '">';        
        html += me._headHtml;
        html += '</table>';
        $('#' + me.frameId).append(html);
        
    }

    /**
     * 获取Id
     */
    Twi.DataTable.prototype.getId = function () {
        return this.id;
    }

    /**
     * 加载数据
     * @data: 【必填参数】，record对象数组，一般传twi.data
     */
    Twi.DataTable.prototype.loadData = function (data) {
        if (!(data  instanceof Array)) {
            return;
        }
        this._data = data;
        //先清空数据
        $('#' + this.id).children('tbody').remove();
        var html = '';
        html += '<tbody>';
        var rowNum = 1;
        for (var i = 0; i < data.length; i++) {
            html += '<tr rowIndex="'+i+'">';
            if (this.config.needRowNumber) {
                html += '<td style="text-align:center;">' + rowNum + '</td>'
                rowNum++;
            }
            for(var j=0;j<this.config.columns.length;j++){
                html += '<td>' + data[i][this.config.columns[j].fieldName] + '</td>';
            }
            html += '</tr>';
        }
        html += '</tbody>';
        $('#' + this.id).append(html);

        var tableSelf = this;

        //添加选择事件
        $('#' + this.id).children('tbody').children('tr').off('click').on('click', function () {
            if (!$(this).data('rowIndex')) {
                //数据缓存
                $(this).data('rowIndex', $(this).attr('rowIndex'));
                $(this).data('rowData',tableSelf._data[$(this).data('rowIndex')]);
            }

            //记录最后选择的信息
            tableSelf._lastSelected = {
                rowIndex: $(this).data('rowIndex'),
                rowData:$(this).data('rowData')
            };

            if (!tableSelf.config.multiSelect) {
                //单选
                $('#' + tableSelf.id).children('tbody').children('tr').removeClass('twiSelected');
                $(this).addClass('twiSelected');
            }

            //自定义事件
            tableSelf.fireEvent("rowclick", {
                tableSelf: tableSelf,               
                rowData: $(this).data('rowData'),
                rowIndex: $(this).data('rowIndex')
            });
        });
    }

    /**
     * 获取选择的集合
     */
    Twi.DataTable.prototype.getSelections = function () {
        var selections = [];
        $(this).children('tbody .twiSelected').each(function (index) {
            selections.push($(this).data('rowData'));
        });
        return selections;
    }

    /**
     * 添加事件
     */
    Twi.DataTable.prototype.addListener = function (eventName, fn) {
        if (typeof this._handlers[eventName] == 'undefined') {
            this._handlers[eventName] = [];
        }
        if (typeof fn == "function") {
            this._handlers[eventName].push(fn);
        }
    }
    Twi.DataTable.prototype.on = Twi.DataTable.prototype.addListener;

    /**
     * 移除事件
     */
    Twi.DataTable.prototype.removeListener = function (eventName) {
        if (this._handlers[eventName] instanceof Array) {
            this._handlers[eventName] = undefined;
        }
    }

    Twi.DataTable.prototype.un = Twi.DataTable.prototype.removeListener;

    /**
     * 触发事件
     * @eventName: 事件名称
     * @args: 参数对象
     */
    Twi.DataTable.prototype.fireEvent = function (eventName, args) {
        args = args || {};
        if (this._handlers[eventName] instanceof Array) {
            var fns = this._handlers[eventName];
            for (var i = 0; i < fns.length; i++) {
                fns[i](args);
            }
        }
    }

})(window.jQuery);

